home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 4
/
The 640 Meg Shareware Studio CD-ROM Volume IV (Data Express)(1994).ISO
/
clang
/
asyam.zip
/
ISR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-06-24
|
7KB
|
290 lines
#include <dos.h>
#include "async.h"
extern int UART_ports[];
extern int UART_interrupts[];
extern int UART_onmask[];
extern int UART_offmask[];
extern struct async_portS async_port[4];
extern int MSRStatus[NUMBEROFPORTS];
extern int LSRStatus[NUMBEROFPORTS];
// Prototypes for ISR's
void interrupt UART_ISR1(void);
void interrupt UART_ISR2(void);
void interrupt UART_ISR3(void);
void interrupt UART_ISR4(void);
// Prototypes for ISR utilities.
static void near ISRmodem(int comport);
static void near ISRtx(int comport);
static void near ISRrx(int comport);
static void near ISRstatus(int comport);
void init_ISR(int comport)
{
int icu, mcr;
asm cli;
// Get old interrupt vector
async_port[comport].oldISR = getvect(UART_interrupts[comport]);
// Set new interrupt vector
switch (comport) {
case COM1:
setvect(UART_interrupts[comport], UART_ISR1);
break;
case COM2:
setvect(UART_interrupts[comport], UART_ISR2);
break;
case COM3:
setvect(UART_interrupts[comport], UART_ISR3);
break;
case COM4:
setvect(UART_interrupts[comport], UART_ISR4);
break;
}
// Set OUT2 bit to enable interrupts
mcr = inportb(UART_ports[comport]+MCR);
mcr |= MCR_OUT2;
outportb(UART_ports[comport]+MCR, mcr);
// Enable interrupts we want
outportb(UART_ports[comport]+IER, 0x08);
// Unmask the interrupts in the ICU
icu = inportb(0x21);
icu &= UART_onmask[comport];
outportb(0x21, icu);
asm sti;
}
void deinit_ISR(int comport)
{
int icu;
// Return the old interrupt vector to normal
setvect(UART_interrupts[comport], async_port[comport].oldISR);
// Remask the interrupts in the ICU
icu = inportb(0x21);
icu |= UART_offmask[comport];
outportb(0x21, icu);
}
// Interrupt Service Routines
void interrupt far UART_ISR1() // ISR for COM1
{
int iir;
int done = 0;
while (!done) {
iir = inportb(UART_ports[COM1]+IIR);
if (iir&1) {
done = 1;
} else {
iir&=6;
iir>>=1;
switch (iir) {
case 0:
ISRmodem(COM1);
break;
case 1:
ISRtx(COM1);
break;
case 2:
ISRrx(COM1);
break;
case 3:
ISRstatus(COM1);
break;
}
}
}
outport(0x20, 0x20);
}
void interrupt far UART_ISR2() // ISR for COM2
{
int iir;
int done = 0;
while (!done) {
iir = inportb(UART_ports[COM2]+IIR);
if (iir&1) {
done = 1;
} else {
iir&=6;
iir>>=1;
switch (iir) {
case 0:
ISRmodem(COM2);
break;
case 1:
ISRtx(COM2);
break;
case 2:
ISRrx(COM2);
break;
case 3:
ISRstatus(COM2);
break;
}
}
}
outport(0x20, 0x20);
}
void interrupt far UART_ISR3() // ISR for COM3
{
int iir;
int done = 0;
while (!done) {
iir = inportb(UART_ports[COM3]+IIR);
if (iir&1) {
done = 1;
} else {
iir&=6;
iir>>=1;
switch (iir) {
case 0:
ISRmodem(COM3);
break;
case 1:
ISRtx(COM3);
break;
case 2:
ISRrx(COM3);
break;
case 3:
ISRstatus(COM3);
break;
}
}
}
outport(0x20, 0x20);
}
void interrupt far UART_ISR4() // ISR for COM4
{
int iir;
int done = 0;
while (!done) {
iir = inportb(UART_ports[COM4]+IIR);
if (iir&1) {
done = 1;
} else {
iir&=6;
iir>>=1;
switch (iir) {
case 0:
ISRmodem(COM4);
break;
case 1:
ISRtx(COM4);
break;
case 2:
ISRrx(COM4);
break;
case 3:
ISRstatus(COM4);
break;
}
}
}
outport(0x20, 0x20);
}
void near ISRmodem(int comport)
{
MSRStatus[comport] = inportb(UART_ports[comport]+MSR);
}
void near ISRtx(int comport)
{
int tst;
// Read from buffer and transmit -- Only does one character right now, no fifo support YET.
while (1) {
if (async_port[comport].txbuflength) {
// There is something waiting to be sent, send it
outportb(UART_ports[comport], async_port[comport].txbuf[async_port[comport].txtail]);
// Move buffer tail
async_port[comport].txtail++;
async_port[comport].txbuflength--;
if (async_port[comport].txtail == TXBUFSIZE) {
async_port[comport].txtail = 0;
}
tst = inport(UART_ports[comport]+LSR);
if (tst != 0x20) {
break;
}
} else {
// There is nothing, so inhibit TX interrupts
tst = inportb(UART_ports[comport]+IER);
tst &= 13;
outportb(UART_ports[comport]+IER, tst);
break;
}
}
}
void near ISRrx(int comport)
{
int rx, tst;
int done = 0;
while (!done) {
rx = inportb(UART_ports[comport]);
// Place character into buffer
async_port[comport].rxbuf[async_port[comport].rxhead] = rx;
// Increment rx buffer head
async_port[comport].rxhead++;
async_port[comport].rxbuflength++;
if (async_port[comport].rxhead == RXBUFSIZE) {
async_port[comport].rxhead = 0;
}
tst = inportb(UART_ports[comport]+LSR);
if (!(tst & 0x01)) { // Check for more in receive
done = 1;
}
if (tst & 0x40) { // Check transmit shift register
ISRtx(comport);
}
}
}
void near ISRstatus(int comport)
{
LSRStatus[comport] = inport(UART_ports[comport]+LSR);
}